package god;

import god.model.SungJuk2VO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;

public class J22SungJuk {
	
	// 성적 처리를 JDBC로 구현 오라클 데이터베이스를 이용해서 성적 데이터 저장, 조회, 수정, 삭제를 처리
	
	// JDBC 객체 및 연결정보
	private static String DRV = "oracle.jdbc.driver.OracleDriver";
	private static String URL = "jdbc:oracle:thin:@112.216.253.124:1521:xe";
	private static String USR = "godraines";
	private static String PWD = "godraines";

	public static void main(String[] args) {
		String result = "";
		Scanner sc = null;
		while ( true ) {
			System.out.println("JDBC 성적 처리 프로그램 v1");
			System.out.println("----------------------------------------");
			System.out.println("1: 성적 데이터 추가");
			System.out.println("2: 성적 데이터 출력");
			System.out.println("3: 성적 데이터 조회");
			System.out.println("4: 성적 데이터 수정");
			System.out.println("5: 성적 데이터 삭제");
			System.out.println("0: 프로그램 종료");
			System.out.println("----------------------------------------");
			System.out.print("실행할 작업을 선택하세요 : ");
			
			sc = new Scanner(System.in);
			
			switch (sc.nextInt()) {
				case 1: result = newSungJuk(); break;
				case 2: result = readSungJuk(); break;
				case 3: result = readOneSungJuk(); break;
				case 4: result = modifySungJuk(); break;
				case 5: result = removeSungJuk(); break;
				case 0 : sc.close(); System.exit(0); break;																					// return;  system.exit(0);         -> 프로그램 종료 
				default : result = "잘못 입력하셨습니다.";
			}
			System.out.println(result);
		}
	}
	
	// 성적 데이터 입력
	public static String newSungJuk() {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String result = "";
		String sql = " insert into SungJuk(sjno, name, kor, eng, mat, tot, avgs, grd) values(sjno.nextval,?,?,?,?,?,?,?) ";
		Scanner sc = new Scanner(System.in);
		
		System.out.println( "성적 데이터를 입력합니다.");
		System.out.println( "이름, 국어, 영어, 수학 순으로 입력해주세요.");
		SungJuk2VO sj = new SungJuk2VO(sc.next(), sc.nextInt(), sc.nextInt(), sc.nextInt());
		
		computeSungJuk(sj);
		
		// SungJuk 테이블에 데이터 입력
		try {
			Class.forName(DRV);																					// 1. 객체 생성
			conn = DriverManager.getConnection(URL, USR, PWD);							//  2. 연결
			pstmt = conn.prepareStatement(sql);															//  3. 실행할 sql 질의문 생성
				pstmt.setString(1, sj.getName());																// sql문의 ?의 위치를 지정
				pstmt.setInt(2, sj.getKor());
				pstmt.setInt(3, sj.getEng());
				pstmt.setInt(4, sj.getMat());
				pstmt.setInt(5, sj.getTot());
				pstmt.setDouble(6, sj.getAvg());
				pstmt.setString(7, String.valueOf(sj.getGrd()));										// + "" 붙이면 문자로 바뀜, String.ValuesOf() 무엇이든 문자열로
			int cnt = pstmt.executeUpdate();
			
			if (cnt > 0) result = cnt + "건의 데이터가 입력됨";										// cnt만큼 입력됨. executeUpdate는 int형으로 처리된 데이터의 수 리턴
			
		} catch(Exception ex) {
			ex.printStackTrace();
		} finally {
			if (pstmt != null) try { pstmt.close(); } catch (Exception e) {}
			if (conn != null) try { conn.close(); } catch (Exception e) {}
		}
		return result;
	}
	
	
	// 성적 데이터 전체 조회
	public static String readSungJuk() {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;																						// select 문 실행시에만 사용
		String sql = "select * from SungJuk order by sjno";
		StringBuilder sb = new StringBuilder();
		
		System.out.println("전체 성적 데이터를 출력합니다.");

		try {
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);						// sql문 생성. prepareStatement는 미리 컴파일해놓고 사용하기 때문에
			pstmt = conn.prepareStatement(sql);														//  statement보다 빠르고,  '?' 사용으로 인해 보안이 좋다.
			rs = pstmt.executeQuery();																		// rs에 실행한 결과 집합 받기
			
			while (rs.next()) {
				sb.append(rs.getString(1)).append("/").append(rs.getString(2)).append("/").append(rs.getString(3)).append("/").append(rs.getString(4)).append("/")
				.append(rs.getString(5)).append("/").append(rs.getString(6)).append("/").append(rs.getString(7)).append(rs.getString(8)).append("/").append(rs.getString(9)).append("\n");
			}
		} catch (Exception ex) {
			ex.printStackTrace();			
		} finally {
			if (rs != null) try{ rs.close(); } catch(Exception ex) {}
			if (pstmt != null) try{ pstmt.close(); } catch(Exception ex) {}
			if (conn != null) try{ conn.close(); } catch(Exception ex) {}
		}
		return sb.toString();
	}
	
	// 성적 데이터 검색
	public static String readOneSungJuk() {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		Scanner sc = new Scanner(System.in);
		String sql = "select * from sungjuk where name=? order by sjno";
		StringBuilder sb = new StringBuilder();
		
		System.out.println("이름으로 성적 데이터를 조회합니다.");
		System.out.println("조회할 성적 데이터의 이름을 입력해주세요.");
		String name = sc.next();
		
		try {
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, name);
			rs = pstmt.executeQuery();
			
			sb.append("=======================================").append("\n");
			while (rs.next()) {
				sb.append(rs.getString(1)).append("/").append(rs.getString(2)).append("/").append(rs.getString(3)).append("/").append(rs.getString(4)).append("/")
				.append(rs.getString(5)).append("/").append(rs.getString(6)).append("/").append(rs.getString(7)).append(rs.getString(8)).append("/").append(rs.getString(9)).append("\n");
			}
		} catch(Exception ex) {
			ex.printStackTrace();
		} finally {
			if (rs != null) try { rs.close(); } catch (Exception ex) {}
			if (pstmt != null) try { pstmt.close(); } catch (Exception ex) {}
			if (conn != null) try { conn.close(); } catch (Exception ex) {}
		}
		return sb.toString();
	}
	
	// 성적 데이터 수정
	public static String modifySungJuk() {
		String result = "";
		Connection conn = null;
		PreparedStatement pstmt = null;
		Scanner sc = new Scanner(System.in);
		String sql = "update sungjuk set name=?, kor=?, eng=?, mat=?, tot=?, avgs=?, grd=?, regdate=sysdate where name=?";
		
		System.out.println("성적 데이터를 수정합니다.");
		System.out.println("수정할 데이터의 이름을 입력해주세요..");
		String name = sc.next();
		
		System.out.println("이름, 국어, 영어, 수학순으로 입력해주세요");
		SungJuk2VO sj = new SungJuk2VO(sc.next(), sc.nextInt(), sc.nextInt(), sc.nextInt());
		
		computeSungJuk(sj);
		
		try {
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, sj.getName());
				pstmt.setInt(2, sj.getKor());
				pstmt.setInt(3, sj.getEng());
				pstmt.setInt(4, sj.getMat());
				pstmt.setInt(5, sj.getTot());
				pstmt.setDouble(6, ( sj.getAvg() ));
				pstmt.setString(7, String.valueOf(sj.getGrd()));
				pstmt.setString(8, name);
			int cnt = pstmt.executeUpdate();
			
			if (cnt > 0) System.out.println(cnt + "건의 데이터가 수정되었습니다.");
			
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (pstmt != null) try { pstmt.close(); } catch(Exception ex) {}
			if (conn != null) try { conn.close(); } catch(Exception ex) {}
		}
		return result;
	}
	
	// 성적 데이터 삭제
	public static String removeSungJuk() {
		String result = "";
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = "delete from sungjuk where name=?";
		Scanner sc = new Scanner(System.in);
		
		System.out.println("선택한 성적 데이터를 삭제합니다.");
		System.out.println("삭제할 데이터의 이름을 입력하세요.");
		String name = sc.next();
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, name);
			int cnt = pstmt.executeUpdate();
			
			if ( cnt > 0) System.out.println(cnt + "건의 데이터가 삭제되었습니다.");
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (pstmt != null) try { pstmt.close(); } catch (Exception ex) {}
			if (conn != null) try { conn.close(); } catch (Exception ex) {}
		}
		return result;
	}
	
	// 성적 데이터 총점, 평균, 학점 계산
	public static void computeSungJuk(SungJuk2VO sj) {
		String dfmt = "###.##";
		sj.setTot(sj.getKor() + sj.getEng() + sj.getMat());
		
		DecimalFormat df = new DecimalFormat(dfmt);									// sj.setAvg = (double)sj.getTot / 3 을 할 경우 소숫점이 많이 나오는데
		String avg = df.format((double)sj.getTot() / 3);											// DecimalFormat()을 사용해서 문자형 "000.00", "###.##" 을 이용해 출력 하면
		sj.setAvg(Double.parseDouble(avg));														// 내가 지정한 형식의 문자형으로 저장된다. 형변환을 통해 sj.setAvg에 저장을 하면 된다.
																															// double 형으로 저장 해야 하기 때문에 double.parseDouble(avg)를 한다
		switch ((int)sj.getAvg() / 10 ) {
			case 10 : case 9 : sj.setGrd('수'); break;
			case 8 : sj.setGrd('우'); break;
			case 7 : sj.setGrd('미'); break;
			case 6 : sj.setGrd('양'); break;
			default : sj.setGrd('가');
		}
	}

}
